/*****************************************************************************
*    Copyright (C) 2010 ALi Corp. All Rights Reserved.
*    
*    Company confidential and Properietary information.       
*    This information may not be disclosed to unauthorized  
*    individual.    
*    File: win_diag_energy.c
*   
*    Description: 
*    
*    History: 
*    Date           Athor        Version        Reason
*    ========       ========     ========       ========
*    2010/8/24      Roman         
*        
*****************************************************************************/
#include <sys_config.h>
#include <types.h>
#include <basic_types.h>
#include <mediatypes.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <osal/osal.h>
#ifndef NEW_DEMO_FRAME
#include <api/libpub29/lib_pub27.h>
#include <api/libpub29/lib_as.h>
#else
#include <api/libpub/lib_frontend.h>
#endif	
#include <hld/decv/decv.h>	
#include <api/libosd/osd_lib.h>
#include <api/libtsi/psi_db.h>
	
#include "osdobjs_def.h"
#include "string.id"
#include "images.id"
#include "osd_config.h"
	
#include "menus_root.h"
#include "win_com.h"
#include "win_com_popup.h"
#include "win_com_list.h"

#define QE_PRINTF(...)
#define RGB16(word) (0x8000|(word))
#define RGB24_RGB1555(R,G,B) (0x8000|(((R)>>3)<<10)|(((G)>>3)<<5)|((B)>>3)) //RGB888 to ARGB1555

#define CAPTURE_BUFFER_LEN	(1024*4)
#define MOVE_SPEED_LOW	2
#define MOVE_SPEED_HIGH	50

#define FIGURE_HIGHT 	400
#define FIGURE_WIDTH	512

#define COOR_WIDTH		510
#define COOR_HIGHT		400
#define COOR_TOP		(W_T+40)
#define COOR_LEFT		(W_L+100)
#define COOR_X_START	(COOR_LEFT+40)
#define COOR_Y_START	(COOR_TOP+410)

#define COOR_X_END		(COOR_X_START+FIGURE_WIDTH)
#define COOR_Y_END		(COOR_Y_START-FIGURE_HIGHT)

#define FIGURE_COLOR	RGB24_RGB1555(0,0,0)
#define COOR_COLOR		RGB24_RGB1555(0,0xff,0)
#define CXCY_COLOR		RGB24_RGB1555(0xff,0,0)
#define BG_COLOR		RGB16(0x635A)

#define W_L	80
#define W_T	10
#define W_W	900
#define W_H	600
	
#define TXT_INFO_W 	90
#define TXT_INFO_H	44
#define TXT_INFO_T 	(W_T + 30)
#define TXT_INFO_L 	(W_L + 20)

#define TXT_FOCUS_W (W_W - 120)
#define TXT_FOCUS_H	44
#define TXT_FOCUS_T (W_T + 80 + COOR_HIGHT)
#define TXT_FOCUS_L (W_L + 60)

#define TXT_HELP_W 	(W_W-120)
#define TXT_HELP_H	44
#define TXT_HELP_T 	(TXT_FOCUS_T + 44)
#define TXT_HELP_L 	TXT_FOCUS_L
	
#define PROG_WIN_SH_IDX         WSTL_POP_WIN_01_8BIT
#define TXT_INFO_IDX            WSTL_TEXT_30_8BIT

static UINT32 diag_capture_freq;
static UINT32 *diag_capture_buffer = NULL;
static UINT32 diag_capture_max_value;
static UINT8  diag_capture_max_v_parity;
static struct nim_device *diag_capture_nim;

static UINT32 virtual_dir_x; //COOR_Y_START; Horizontal Coordinate y position
static UINT32 virtual_dir_y; //COOR_X_START; Vertial Coordinate x position
	
static VACTION win_energy_keymap(POBJECT_HEAD pObj, UINT32 key);
static PRESULT win_energy_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2);

extern TEXT_FIELD text_eng_infoy;
extern TEXT_FIELD text_eng_focus;
extern TEXT_FIELD text_eng_help;
extern CONTAINER g_con_diag_energy;

#define LDEF_TXT(root,varTxt,nxtObj,l,t,w,h,str)		\
	DEF_TEXTFIELD(varTxt,root,nxtObj,C_ATTR_ACTIVE,0, \
	0,0,0,0,0, l,t,w,h, TXT_INFO_IDX,TXT_INFO_IDX,TXT_INFO_IDX,TXT_INFO_IDX,   \
	NULL,NULL,	\
	C_ALIGN_CENTER|C_ALIGN_VCENTER, 0,0,0,str)

#define LDEF_WIN(varWnd,nxtObj,l,t,w,h,sh,nextObj,focusID)		\
	DEF_CONTAINER(varWnd,NULL,NULL,C_ATTR_ACTIVE,0, \
		0,0,0,0,0, l,t,w,h, sh,sh,sh,sh,   \
		win_energy_keymap,win_energy_callback,	\
		nextObj, focusID,1)

LDEF_TXT(&g_con_diag_energy,text_eng_infoy,&text_eng_focus,TXT_INFO_L, TXT_INFO_T,TXT_INFO_W,TXT_INFO_H, display_strs[0])
LDEF_TXT(&g_con_diag_energy,text_eng_focus,&text_eng_help, TXT_FOCUS_L,TXT_FOCUS_T,TXT_FOCUS_W,TXT_FOCUS_H,display_strs[1])
LDEF_TXT(&g_con_diag_energy,text_eng_help, NULL,           TXT_HELP_L,TXT_HELP_T,TXT_HELP_W,TXT_HELP_H,display_strs[2])

LDEF_WIN(g_con_diag_energy,NULL,W_L,W_T,W_W,W_H,PROG_WIN_SH_IDX,&text_eng_infoy,1);


//;

void set_capture_freq(struct nim_device *nim, UINT32 freq)
{
	diag_capture_nim = nim;
	diag_capture_freq = freq;
}

static void get_energy()
{
	UINT32 i;
	UINT32 cap_param[3];

	cap_param[0] = diag_capture_freq;
	cap_param[1] = (UINT32)diag_capture_buffer;
	cap_param[2] = 0;

	diag_capture_max_value = 0;
	nim_ioctl_ext(diag_capture_nim, NIM_DRIVER_START_CAPTURE, &cap_param);

	// Get Max data for energy;
	for(i = 0; i < 1024; i++)
	{
		if(diag_capture_max_value < diag_capture_buffer[i])
		{
			diag_capture_max_value = diag_capture_buffer[i]; 
			if(i%2)
				diag_capture_max_v_parity = 1;
			else
				diag_capture_max_v_parity = 0;
		}
	}	
	QE_PRINTF(diag_capture_max_value);
	QE_PRINTF(diag_capture_max_v_parity);
}

static void draw_energy_figure()
{
	UINT32 i;
	UINT32 dwDotTop;

	if(diag_capture_max_value == 0)
		return;
	// Draw the energy figure
	for(i = 0; i < 512; i++)
	{
		dwDotTop = diag_capture_buffer[i*2+diag_capture_max_v_parity]*FIGURE_HIGHT/diag_capture_max_value;
		OSD_DrawPixel(i+COOR_X_START, COOR_Y_START - dwDotTop, FIGURE_COLOR, NULL);
#if 0
		if(i%16==0)
			QE_PRINTF("\n");		
		QE_PRINTF("%d ",dwDotTop);
#endif		
	}
}

static void DrawVirtualCX(UINT32 color)
{
	if(virtual_dir_x != COOR_Y_START)
	{	
		OSD_DrawHorLine(COOR_X_START, virtual_dir_x, COOR_WIDTH, color, NULL);
	}
}

static void DrawVirtualCY(UINT32 color)
{
	if(virtual_dir_y != COOR_X_START)
	{		
		OSD_DrawVerLine(virtual_dir_y, COOR_TOP, COOR_HIGHT, color, NULL);
	}
}

static void DrawCxCyFocus()
{
	UINT8 focus[32];
	UINT32 x,y;

	if(virtual_dir_y < COOR_X_START)
		virtual_dir_y = COOR_X_START;

	if(virtual_dir_x > COOR_Y_START)
	{
		virtual_dir_x = COOR_Y_START;
	}
	x = (virtual_dir_y-COOR_X_START)*2;
	y = (COOR_Y_START-virtual_dir_x)*diag_capture_max_value/FIGURE_HIGHT;
	sprintf(focus, "mid freq:%d. (%d,%d)",diag_capture_freq,x,y);
	QE_PRINTF("energy:(%d,%d), osd pos(%d:%d)\n",x,y,virtual_dir_y,virtual_dir_x);
	OSD_SetTextFieldContent(&text_eng_focus,STRING_ANSI, (UINT32)focus);
	OSD_DrawObject((POBJECT_HEAD)&text_eng_focus,C_UPDATE_ALL);	
}

static BOOL OnChangeVirtualCX(BOOL bDirDown, UINT32 step)
{
	UINT32 dwNewC;

	if(bDirDown)
	{
		if(virtual_dir_x+step > COOR_Y_START)
			dwNewC = COOR_Y_END+step;
		else
			dwNewC = virtual_dir_x+step;
	}
	else
	{
		if(virtual_dir_x < COOR_Y_END+step)
			dwNewC = COOR_Y_START-step;
		else
			dwNewC = virtual_dir_x-step;
	}

	OSD_RECT rect;
	rect.uLeft = COOR_X_START;
	rect.uTop= virtual_dir_x;
	rect.uWidth= FIGURE_WIDTH;
	rect.uHeight= 1;
	OSD_SetClipRect(CLIP_INSIDE_RECT,&rect);
	DrawVirtualCX(BG_COLOR);
	draw_energy_figure();
	DrawVirtualCY(CXCY_COLOR);
	OSD_ClearClipRect();
	virtual_dir_x = dwNewC;
	DrawVirtualCX(CXCY_COLOR);
	DrawCxCyFocus();
	return TRUE;
}

static BOOL OnChangeVirtualCY(BOOL bDirRight, UINT32 step)
{
	UINT32 dwNewC;

	if(bDirRight)
	{
		if(virtual_dir_y+step > COOR_X_END)
			dwNewC = COOR_X_START+step;
		else
			dwNewC = virtual_dir_y+step;
	}
	else
	{
		if(virtual_dir_y<COOR_X_START+step)
			dwNewC = COOR_X_END-step;
		else
			dwNewC = virtual_dir_y-step;
	}

	OSD_RECT rect;
	rect.uLeft = virtual_dir_y;
	rect.uTop= COOR_TOP;
	rect.uWidth= 1;
	rect.uHeight= FIGURE_HIGHT;
	OSD_SetClipRect(CLIP_INSIDE_RECT,&rect);
	DrawVirtualCY(BG_COLOR);
	draw_energy_figure();
	DrawVirtualCX(CXCY_COLOR);
	OSD_ClearClipRect();
	virtual_dir_y = dwNewC;
	DrawVirtualCY(CXCY_COLOR);
	DrawCxCyFocus();
	return TRUE;
}

static UINT8 MoveVirtualCoordinate(UINT8 msgCode)	
{
	UINT8 result = PROC_PASS;

	switch(msgCode)
	{
		case V_KEY_RIGHT:
			OnChangeVirtualCY(TRUE, MOVE_SPEED_LOW);
			break;
		case V_KEY_6:
			OnChangeVirtualCY(TRUE, MOVE_SPEED_HIGH);
			break;

		case V_KEY_LEFT:
			OnChangeVirtualCY(FALSE, MOVE_SPEED_LOW);
			break;
		case V_KEY_4:
			OnChangeVirtualCY(FALSE, MOVE_SPEED_HIGH);
			break;

		case V_KEY_UP:
			OnChangeVirtualCX(FALSE, MOVE_SPEED_LOW);
			break;
		case V_KEY_2:
			OnChangeVirtualCX(FALSE, MOVE_SPEED_HIGH);
			break;

		case V_KEY_DOWN:
			OnChangeVirtualCX(TRUE, MOVE_SPEED_LOW);
			break;
		case V_KEY_8:
			OnChangeVirtualCX(TRUE, MOVE_SPEED_HIGH);
			break;
		default:
			break;
	}

	return result;
}

static VACTION win_energy_keymap(POBJECT_HEAD pObj, UINT32 key)
{
	VACTION act;
	
	switch(key)
	{
	case V_KEY_MENU:
	case V_KEY_EXIT:
		act = VACT_CLOSE;
		break;			
	default:	
		act = VACT_PASS;
		break;
	}
	
	return act;
}

static PRESULT win_energy_callback(POBJECT_HEAD pObj, VEVENT event, UINT32 param1, UINT32 param2)
{	
	PRESULT ret = PROC_PASS;
	UINT32	vkey;
	POBJECT_HEAD topmenu;

	switch(event)
	{
	case EVN_PRE_OPEN:
		//api_inc_wnd_count();
		wincom_close_title();
		if(menu_stack_get(0) == (POBJECT_HEAD)&g_win_mainmenu)
		{
			OSD_ClearObject( (POBJECT_HEAD) &g_win_mainmenu, C_UPDATE_ALL);
			topmenu = menu_stack_get_top();
			if(topmenu)
				OSD_ClearObject( topmenu, C_UPDATE_ALL);
		}
		if(diag_capture_buffer == NULL)
		{
			diag_capture_buffer = MALLOC(CAPTURE_BUFFER_LEN);
		}
		get_energy();
		virtual_dir_y = COOR_X_START;
		virtual_dir_x = COOR_Y_START;
		OSD_SetTextFieldContent(&text_eng_infoy, STRING_NUMBER, (UINT32)diag_capture_max_value);
		OSD_SetTextFieldContent(&text_eng_help, STRING_ANSI, (UINT32)"Up Down Left Right Move Slow, 2,4,6,8 Move Fast");
		break;
	case EVN_POST_OPEN:		
		// Draw coordinate
		OSD_DrawHorLine(COOR_X_START-40, COOR_Y_START, COOR_WIDTH+100, COOR_COLOR, NULL);
		OSD_DrawVerLine(COOR_X_START, COOR_TOP, COOR_HIGHT+60, COOR_COLOR, NULL);		
		draw_energy_figure();
		DrawCxCyFocus();
		
		break;
	case EVN_MSG_GOT:
		break;
	case EVN_PRE_CLOSE:
		if(diag_capture_buffer)
		{
			FREE(diag_capture_buffer);
			diag_capture_buffer = NULL;
		}
		break;
	case EVN_POST_CLOSE:
		//api_dec_wnd_count();
		if(menu_stack_get(0) == (POBJECT_HEAD)&g_win_mainmenu)
			OSD_TrackObject( (POBJECT_HEAD) &g_win_mainmenu, C_UPDATE_ALL);	
		
		break;

	case EVN_UNKNOWNKEY_GOT:
		ap_hk_to_vk(0,param1,&vkey);
		MoveVirtualCoordinate(vkey);
		break;
	default:
		break;
	}

	return ret;
}


